/*    This file is part of nit.
 *
 *    Nit is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU Lesser General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    Nit is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public License
 *    along with nit.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef SET_H
#define SET_H

#include <stdint.h>

#include "dispose.h"
#include "list.h"

#define set_foreach(set, bin, entry)					\
	for (bin = 0; bin < bin_num[(set)->bin_pos]; ++bin)		\
		for ((entry) = (set)->bins[bin]; (entry);		\
		     (entry) = (entry)->next)

typedef struct Set_key {
	void *dat;
	uint32_t key_len;
} Set_key;

typedef struct Set_entry {
	void *dat;
	uint32_t key_len;
	uint32_t hash;
	struct Set_entry *next;
} Set_entry;

typedef void (*Set_dispose)(Disposer *disposer, uint32_t key_len, void *dat);

typedef struct {
        Disposer *disposer;
	uint32_t size;
	int bin_pos;
	Set_entry **bins;
} Set;

const int bin_num[31];

Nit_error
set_init(Set *set, Disposer *disposer, int bin_pos);

void
set_dispose(Set *set, Set_dispose set_dispose);

Nit_error
set_add(Set *set, uint32_t key_len, const void *dat);

Nit_error
set_remove(Set *set, uint32_t key_len, void **dat);

int
set_get(const Set *set, uint32_t key_len, void **dat);

int
set_contains(const Set *set, uint32_t key_len, const void *dat);

int
set_subset(const Set *super, const Set *sub);

int
set_equal(const Set *set1, const Set *set2);

Nit_error
set_fill(Set *src, const Set *des);

Nit_error
set_compl(Set *des, const Set *src, const Set *dif);

Nit_error
set_inter(Set *des, const Set *src1, const Set *src2);

Nit_error
set_list(const Set *set, List *list, int init, int copy);

#endif
